package com.itlong.cloud.controller.app;

import com.itlong.cloud.POJO.DTO.operate.OperateAllotProjectDTO;
import com.itlong.cloud.POJO.DTO.operate.OperateAppPackageGetPageDTO;
import com.itlong.cloud.POJO.PO.AppPackagePO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.operate.OperateAllotProjectVO;
import com.itlong.cloud.POJO.VO.operate.OperateAppPackageGetPageVO;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.OperateErrorCodeEnum;
import com.itlong.cloud.noncore.operate.IOperateAppPackageServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      运营-APP管理-套餐管理控制器
 * </desc>
 *
 * @createDate 2017/11/01
 */
@RestController
@RequestMapping("/appManage/package/")
public class OperateAppPackageController extends BaseController{
    @Autowired
    IOperateAppPackageServiceClient iOperateAppPackageServiceClient;

    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;

    @Autowired
    RedisService redisService;
    /**
     * <desc>
     *      获取分页列表
     * </desc>
     *
     * @param dto 查询参数DTO
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/01
     */
    //@AuthAccessRequired
    @RequestMapping(path = "getPage",method = RequestMethod.POST)
    @ResponseBody
    public Object getAppPackagePage(OperateAppPackageGetPageDTO dto){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            dto= HttpProtocolUtil.parseRequestParamToDTO(OperateAppPackageGetPageDTO.class,request);
            Page<OperateAppPackageGetPageVO> page=iOperateAppPackageServiceClient.getPage(dto);
            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),page);
        } catch (Exception e) {
            throw new DataAccessException("【运营_APP管理_套餐管理getPage】获取分页列表失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      添加套餐
     * </desc>
     *
     * @param appPackagePO 套餐实体
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/01
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.APP_PACKAGE_OPERATE_LOG_SAVE)
    @RequestMapping(path = "save",method = RequestMethod.POST)
    @ResponseBody
    public Object saveAppPackage(AppPackagePO appPackagePO){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            appPackagePO= HttpProtocolUtil.parseRequestParamToDTO(AppPackagePO.class,request);
            String appPackageId = iOperateAppPackageServiceClient.save(appPackagePO);
            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), appPackageId);
        } catch (Exception e) {
            throw new DataAccessException("【运营_APP管理_套餐管理save】添加套餐失败",e);
        }
        return messageVO;

    }

    /**
     * <desc>
     *      修改套餐
     * </desc>
     *
     * @param appPackagePO 套餐实体
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/01
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.APP_PACKAGE_OPERATE_LOG_UPDATE)
    @RequestMapping(path = "update",method = RequestMethod.POST)
    @ResponseBody
    public Object updateAppPackage(AppPackagePO appPackagePO){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            appPackagePO= HttpProtocolUtil.parseRequestParamToDTO(AppPackagePO.class,request);
            iOperateAppPackageServiceClient.update(appPackagePO);
            messageVO=new MessageVO(appPackagePO.getAppPackageId(), BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-_APP管理_套餐管理update】更新套餐失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      查询单条套餐
     * </desc>
     *
     * @param appPackagePO 套餐实体
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/01
     */
    @AuthAccessRequired
    @RequestMapping(path = "getOne",method = RequestMethod.POST)
    @ResponseBody
    public Object getAppPackage(AppPackagePO appPackagePO){
        MessageVO messageVO;
        try{
            HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            appPackagePO= HttpProtocolUtil.parseRequestParamToDTO(AppPackagePO.class,request);
            appPackagePO=iOperateAppPackageServiceClient.getOne(appPackagePO);
            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),appPackagePO);
        }catch (Exception e){
            throw new DataAccessException("【运营_APP管理_套餐管理getOne】获取单条套餐失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      删除套餐
     * </desc>
     *
     * @param appPackageIds 功能id数组字符串 ，号分隔
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/01
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.APP_PACKAGE_OPERATE_LOG_DELETE)
    @RequestMapping(path = "delete",method = RequestMethod.POST)
    @ResponseBody
    public Object deleteAppPackage(String appPackageIds){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            appPackageIds=request.getAttribute("appPackageIds")==null?null:request.getAttribute("appPackageIds").toString();
            if (StringUtils.isBlank(appPackageIds)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<String> projectIds=iOperateAppPackageServiceClient.getAppPackageProjectIds(appPackageIds);
            List<String> sceneIds = iOperateAppPackageServiceClient.getSceneIdByPackageId(appPackageIds);
            if (projectIds.size() > 0 || sceneIds.size() >0){
                return new MessageVO(OperateErrorCodeEnum.OPERATE_PACKAGE_RELATION_DATA_EXIST_ERR.getErrorCode());
            }

            iOperateAppPackageServiceClient.delete(appPackageIds);
            messageVO=new MessageVO(appPackageIds,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch(Exception e){
            throw new DataAccessException("【运营_APP管理_功能管理delete】删除套餐失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      套餐分配功能
     * </desc>
     *
     * @param appFunctionIds 功能id 多个,号分隔
     * @param appPackageId  套餐id
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/01
     */
    @LoggerInfo(operateDesc = LogDescConstant.APP_PACKAGE_LOG_ALLOT_FUNCTION_SAVE)
    @RequestMapping(path = "allotFunction",method = RequestMethod.POST)
    @ResponseBody
    public Object allotAppFunction(String appFunctionIds, String appPackageId,Integer systemType){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            appFunctionIds= request.getAttribute("appFunctionIds")==null?null:request.getAttribute("appFunctionIds").toString();
            appPackageId= request.getAttribute("appPackageId")==null?null:request.getAttribute("appPackageId").toString();
            systemType = request.getAttribute("systemType") == null ? null : Integer.parseInt(request.getAttribute("systemType").toString());
            if (systemType == null){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (!NumberHandlerUtil.isInRange(systemType,1,3)){
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            //同步物业菜单
            if (systemType == 3 && redisService.get(RedisConstant.PROPERTY_PACKAGE_HANDLER_PROPERTY_FUNCION_KEY + appPackageId) != null){
                return new MessageVO(OperateErrorCodeEnum.OPERATE_PROPERTY_FUNCTION_SYNC_ERR.getErrorCode());
            }
            iOperateAppPackageServiceClient.allotFunction(appFunctionIds,appPackageId,systemType);
            messageVO=new MessageVO(appFunctionIds+"|"+appPackageId, BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch(Exception e){
            throw new DataAccessException("【运营_APP管理_套餐管理allotFunction】功能分配失败",e);
        }
        return messageVO;
    }


    /**
     * <desc>
     *      获取项目分配列表
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/12
     */
    @RequestMapping(path = "getAllotProjectPage",method = RequestMethod.POST)
    @ResponseBody
    public Object getAllotProjectPage(OperateAllotProjectDTO pageDTO,String appPackageId){
        MessageVO messageVO;
        try{
            HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            pageDTO=HttpProtocolUtil.parseRequestParamToDTO(OperateAllotProjectDTO.class,request);
            appPackageId=request.getAttribute("appPackageId")==null?null:request.getAttribute("appPackageId").toString();
            //获取项目列表
            Page<OperateAllotProjectVO> page = iOperateProjectServiceClient.getAllotProjectPage(pageDTO);
            //当前套餐已拥有的项目id
            List<String> projectIds=iOperateAppPackageServiceClient.getAppPackageProjectIds(appPackageId);
            List<String> otherProjectIds = iOperateAppPackageServiceClient.getOtherProjectIds(appPackageId);
            page.getRows().forEach(row->{
                if(projectIds.stream().filter(
                        projectId->projectId.equals(row.getProjectId())
                ).findFirst().isPresent()){
                    row.setHaveProject("true");
                }
                //云半径多场景项目需求，若项目分配了套餐，还可以分配下一套餐，只不过要把之前项目的套餐删除
//                if (otherProjectIds.stream().filter(
//                        otherProjectId->otherProjectId.equals(row.getProjectId())
//                ).findFirst().isPresent()){
//                    row.setHaveProject("forbidden");
//                }
            });
            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),page);
        }catch (Exception e){
            throw new DataAccessException("【运营_项目管理_项目getProjectList】获取项目下拉列表失败",e);
        }
        return messageVO;
    }


    /**
     * <desc>
     *      套餐分配项目
     * </desc>
     *
     * @param allotProjectIds 待分配的项目id
     * @param appPackageId  套餐id
     * @param projectIds 当前页所有项目id
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/01
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.APP_PACKAGE_LOG_ALLOT_PROJECT_SAVE)
    @RequestMapping(path = "allotProject",method = RequestMethod.POST)
    @ResponseBody
    public Object allotProject(String appPackageId,String allotProjectIds,String projectIds){
        MessageVO messageVO;
        try {
            HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            appPackageId=request.getAttribute("appPackageId")==null?null:request.getAttribute("appPackageId").toString();
            allotProjectIds=request.getAttribute("allotProjectIds")==null?"":request.getAttribute("allotProjectIds").toString();
            projectIds=request.getAttribute("projectIds")==null?null:request.getAttribute("projectIds").toString();

            //判断被取消的项目中是否包含未绑定套餐的项目
            if (projectIds == null || appPackageId == null){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<String> projectIdList = StringHandlerUtil.splitStringList(projectIds);
            if (allotProjectIds != null){
                projectIdList.removeAll(StringHandlerUtil.splitStringList(allotProjectIds));
            }

            if (projectIdList!= null && projectIdList.size() > 0){
                List<Map<String, Object>> packageList =  iOperateAppPackageServiceClient.checkProjectsIsBindPackage(projectIdList);
                for (String projectId : projectIdList){
                    for (Map<String, Object> packageMap : packageList){
                        if (packageMap.get("projectId") != null && projectId.equals(packageMap.get("projectId"))
                                && packageMap.get("appPackageId") != null && appPackageId.equals(packageMap.get("appPackageId"))){
                            //存在项目取消绑定当前套餐后无套餐
                            return new MessageVO(OperateErrorCodeEnum.OPERATE_PROJECT_NO_PACKAGE_ERR.getErrorCode());
                        }
                    }
                }
            }

            iOperateAppPackageServiceClient.allotPackageProject(appPackageId,allotProjectIds,projectIds);
            messageVO=new MessageVO(appPackageId+"|"+allotProjectIds+"|"+projectIds, BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch(Exception e){
            throw new DataAccessException("【运营_APP管理_套餐管理allotProject】套餐分配项目失败",e);
        }
        return messageVO;
    }
}
